/**
 * 附件上传组件
 * by zls
 *
 */
import React from 'react';
import { PrimaryGhostC, PrimaryC } from '@/src/comps';
import { InfoCircleOutlined } from '@ant-design/icons';
import { Upload, message } from 'antd';
import styles from './styles.less';
import UploadList from './uploadList';
import PropTypes from 'prop-types';
import { exportFile } from '../../../utils/commonFunc';

class UploadC extends React.Component {
  // 默认值
  static defaultProps = {
    value: null, // 默认null
    title: '上传附件', // 默认'上传附件'
    loading: false, // 默认false
    fileListLoading: false, // 默认false
    disabled: false, // 默认false
    primaryProps: {}, // 按钮 prop
    multiple: false, // 默认false
    showUploadList: true, // 是否展示文件列表
    type: 1, // 默认自动上传
    action: 'gateway/file/maat-admin/file/upload', // 上传地址
    onUpload: () => {},
    remove: () => {}, // 删除调用
    isDowm: true, // 默认ture
    isDelete: true, // 默认ture
    accept: '', // 默认可上传全部类型
    onRef: () => {},
    data: {},
    isButton: true,
    hasTemplate: false, // 是否显示下载模版按钮
    downloadUrl: '', // 下载模版地址
    downloadParams: '', // 下载模版参数
  };

  state = {
    fileList: [],
    loading: false,
  };

  componentDidMount() {
    this.props.onRef(this);
    if (this.props.value) {
      this.changeFileList(this.props.value);
    }
  }

  UNSAFE_componentWillReceiveProps(nextProps) {
    if (JSON.stringify(nextProps.value) !== JSON.stringify(this.props.value)) {
      if (nextProps.value) {
        this.changeFileList(nextProps.value);
      }
    }
  }

  // 将filelist 转换成upload组件接收的样子
  changeFileList = (data) => {
    // 接受data 为bool类型时 data.map函数报错
    if (Object.prototype.toString.call(data) === '[object Boolean]') {
      return;
    }
    this.setState(
      {
        fileList: data.map((item) => {
          return {
            uid: item.value,
            name: item.title,
            status: 'done',
            value: item.value,
          };
        }),
      },
      () => {
        this.fileListChange();
      },
    );
  };

  // 获取文件列表
  getFileList = () => {
    let successData = [];
    console.log('this.state.fileList', this.state.fileList);
    if (this.state.fileList.length) {
      // 文件上传部分
      const errorData = this.state.fileList.filter((item) => item.status == 'error');
      if (errorData.length) {
        message.error('存在上传失败文件,请删除或者重新上传！');
        return null;
      }
      if (this.props.type == 2) {
        successData = this.state.fileList;
      } else {
        successData = this.state.fileList.map((item) => {
          return { title: item.name, value: item.value };
        });
      }
    }
    return successData;
  };

  // 文件列表变化
  fileListChange = () => {
    this.props.fileListChange && this.props.fileListChange(this.state.fileList);
  };

  ajaxRequest(method, url, type) {
    return new Promise((resolve, reject) => {
      const req = new XMLHttpRequest();
      req.open(method, url, true);
      req.setRequestHeader('Content-Type', 'application/json');
      req.setRequestHeader('hToken', localStorage.getItem('antd-pro-token'));
      const ivUser = localStorage.getItem('antd-pro-userId');
      if (ivUser) {
        // 资管环境
        req.setRequestHeader('iv-user', ivUser);
      }
      req.responseType = type;
      req.onreadystatechange = () => {
        // readyState == 4说明请求已完成
        if (req.readyState === 4) {
          const data = req.response;
          // # 获取请求头Content-Type的值，用来判断是否是文件流下载
          const type = req.getResponseHeader('Content-Type');

          if (req.status === 200 || req.status === 304) {
            // # application/json;charset=UTF-8：就是指“无类型”，一般的字节流用于数据传输，非文件下载
            if (type !== 'multipart/form-data;charset=UTF-8') {
              resolve(undefined);
            } else {
              resolve(data);
            }
          } else {
            reject(undefined);
          }
        }
      };
      // 发送数据
      req.send();
    });
  }

  // 下载请求文件流
  queryDownLoadUrl = (id, obj) => {
    const promise = new Promise((resolve, reject) => {
      const queryUrl = `gateway/file/maat-admin/file/download?uniquekey=${id}`;
      this.ajaxRequest('get', queryUrl, 'blob').then((url) => {
        if (url) {
          if ('download' in document.createElement('a')) {
            // 非IE下载
            const elink = document.createElement('a');
            elink.download = obj.name;
            elink.style.display = 'none';
            elink.href = URL.createObjectURL(url);
            document.body.appendChild(elink);
            elink.click();
            URL.revokeObjectURL(elink.href); // 释放URL 对象
            document.body.removeChild(elink);
          } else {
            // IE10+下载
            navigator.msSaveBlob(url, obj.name);
          }
        } else {
          const { fileList } = this.state;
          fileList.map((item) => {
            if (item.value == obj.value) {
              item.status = 'error';
              item.response = '下载地址错误';
            }
          });
          this.setState(
            {
              fileList: [...fileList],
            },
            () => {
              this.fileListChange();
            },
          );
        }
      });
    });
    return promise;
  };

  // 移除文件
  onRemove = (file) => {
    this.props?.remove(file);
    this.setState(
      ({ fileList }) => {
        const index = fileList.indexOf(file);
        const newFileList = fileList.slice();
        newFileList.splice(index, 1);
        return {
          fileList: newFileList,
        };
      },
      () => {
        this.fileListChange();
      },
    );
  };

  render() {
    const { title, action, disabled, loading, accept, onUpload, type, showUploadList, multiple, max, fileListLoading, data, hasTemplate, downloadUrl, downloadParams } = this.props;

    const uploaderProps = {
      accept,
      action,
      multiple,
      data,
      headers: {
        hToken: localStorage.getItem('antd-pro-token'),
        'iv-user': localStorage.getItem('antd-pro-userId'),
      },
      onChange: (info) => {
        // 自动上传
        if (info.file.status === 'uploading') {
          this.setState({ loading: true });
        } else {
          this.setState({ loading: false });
        }
        if (type == 1) {
          if (info.file.status === 'done') {
            onUpload(info.file?.response);
          } else if (info.file.status === 'error') {
            if (info.file.error?.status == 413) {
              message.error('文件过大');
            }
            onUpload(info.file?.response);
          }
        }

        let fileList = [...info.fileList];

        fileList = fileList.map((file) => {
          // 多文件上传 需要遍历数组
          if (file.response && !file.value) {
            const { response } = file;
            if (response && response.value) {
              file.status = 'done';
              file.value = response.value;
            } else {
              file.status = 'error';
            }
          }
          return file;
        });
        // 限制上传文件最大数量
        if (max) {
          fileList = fileList.splice(Number(-max));
        }
        this.setState({ fileList }, () => {
          this.fileListChange();
        });
      },
      fileList: this.state.fileList,
      showUploadList: false,
      beforeUpload: (file) => {
        // 校验文件类型
        return new Promise((resolve, reject) => {
          const flieArr = file.name.split('.');

          const suffix = flieArr[flieArr?.length - 1];
          if (accept == '' || accept.indexOf(suffix) != -1) {
            // 手动上传
            if (type == 2) {
              let fileList = [...this.state.fileList, file];
              // 限制上传文件最大数量
              if (max) {
                fileList = fileList.splice(Number(-max));
              }
              this.setState({ fileList }, () => {
                this.fileListChange();
              });

              onUpload(file);
              return false;
            } else {
              return resolve(file);
            }
          } else {
            message.error('文件类型不支持');
            return false;
          }
        });
      },
    };

    const { isDowm, isDelete, style, styleRow, width, primaryProps = {}, toolTip, isButton } = this.props;
    const templateProps = {
      title: '下载模板',
      style: { marginLeft: '16px' },
      onClick: (e) => {
        e.preventDefault();
        if (downloadUrl) {
          exportFile(downloadUrl, downloadParams);
        }
      },
    };
    return (
      <div className={styles.uploadC} style={style}>
        {disabled ? (
          <>
            <PrimaryGhostC title={title} disabled={disabled} {...primaryProps} />
          </>
        ) : (
          <Upload {...uploaderProps}>{isButton ? <PrimaryGhostC title={title} disabled={disabled} loading={loading || this.state.loading} {...primaryProps} /> : title}</Upload>
        )}
        {hasTemplate ? <PrimaryC {...templateProps} /> : null}
        {toolTip ? (
          <div style={{ color: 'rgba(0, 0, 0, 0.45)', height: '30px' }}>
            <InfoCircleOutlined style={{ color: '#4376FF', marginRight: '10px' }} />
            {toolTip}
          </div>
        ) : (
          ''
        )}
        {showUploadList && (
          <UploadList
            fileList={this.state.fileList}
            isDowm={isDowm}
            isDelete={disabled ? false : isDelete}
            onRemove={this.onRemove}
            onDownload={this.queryDownLoadUrl}
            fileListLoading={fileListLoading}
            styleRow={styleRow ? styleRow : null}
            width={width}
          />
        )}
      </div>
    );
  }
}

// props类型
UploadC.propsTypes = {
  value: PropTypes.array, // 回填的数据 (格式：[{title:'',value:''},{title:'',value:''}])
  accept: PropTypes.string, // 上传文件类型
  title: PropTypes.string, // 显示名称
  type: PropTypes.number, // type=1 自动上传使用默认接口，type = 2获取文件流
  action: PropTypes.string,
  loading: PropTypes.bool, // 按钮加载状态
  fileListLoading: PropTypes.bool, // 文件列表加载状态
  disabled: PropTypes.string, // 是否禁用
  showUploadList: PropTypes.bool, // 是否展示列表
  onUpload: PropTypes.func, // 上传成后的回调
  onRef: PropTypes.func, // 本组件的引用（可用来父组件调用内部方法）
  primaryProps: PropTypes.object, // 按钮props
  remove: PropTypes.func, // 删除调用
  isDowm: PropTypes.bool, // 是否允许下载
  isDelete: PropTypes.bool, // 是否允许删除
  multiple: PropTypes.bool, //
  isButton: PropTypes.bool, // 是否展示button样式
  max: PropTypes.number, // 最多展示多少个  不传默认不限制个数
  hasTemplate: PropTypes.bool, // 是否显示下载模版按钮
  downloadUrl: PropTypes.string, // 下载模版地址
  downloadParams: PropTypes.object, // 下载模版参数
};

export default UploadC;
